package com.atom.module.coroutine.core

sealed class RecursiveList<out T> {
    // 无任何实现的子类
    object Nil : RecursiveList<Nothing>()

    // 一个链子
    class Cons<T>(val head: T, val tail: RecursiveList<T>) : RecursiveList<T>() {
        override fun toString(): String {
            return "${head.toString()} $tail"
        }
    }
}

// 通过自身进行遍历 尾递归 剔除指定key
fun <T> RecursiveList<T>.remove(element: T): RecursiveList<T> {
    return when(this){
        RecursiveList.Nil -> this
        is RecursiveList.Cons -> {
            if(head == element){
                return tail
            } else {
                RecursiveList.Cons(head, tail.remove(element))
            }
        }
    }
}

// 遍历一遍 尾递归 牛逼
tailrec fun <T> RecursiveList<T>.forEach(action: (T) -> Unit) {
    when (this) {
        RecursiveList.Nil -> Unit
        is RecursiveList.Cons -> {
            action.invoke(this.head)
            this.tail.forEach(action)
        }
    }
}

// 用于检出 指定类型的 对象
inline fun <reified T> RecursiveList<Any>.loopOn(crossinline action: (T) -> Unit) = forEach {
    when (it) {
        is T -> action(it)
    }
}
